package com.hunttown.common.sharding.client.datasource;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.sql.DataSource;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.util.CollectionUtils;

public class DefaultMultiDataSourcesService implements MultipleDataSourcesService, ApplicationContextAware, InitializingBean {
    private ApplicationContext springContext;
    private Map<String, String> dataSourceMap;
    private Map<String, Object> dataSourcePoolConfig;

    public DefaultMultiDataSourcesService() {
    }

    public void setDataSourcePool(Map<String, Object> dataSourcePool) {
        this.dataSourcePoolConfig = dataSourcePool;
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.springContext = applicationContext;
    }

    public Map<String, String> getDataSources() {
        if (CollectionUtils.isEmpty(this.dataSourceMap)) {
            this.dataSourceMap = Collections.emptyMap();
        }

        return Collections.unmodifiableMap(this.dataSourceMap);
    }

    public void afterPropertiesSet() throws Exception {
        if (CollectionUtils.isEmpty(this.dataSourcePoolConfig)) {
            throw new IllegalArgumentException("dataSourcePool cann't be null or empty!");
        } else {
            this.dataSourceMap = new HashMap(this.dataSourcePoolConfig.size());
            Iterator i$ = this.dataSourcePoolConfig.entrySet().iterator();

            while (i$.hasNext()) {
                Entry<String, Object> entity = (Entry) i$.next();
                Object value = entity.getValue();
                if (value instanceof DataSource) {
                    throw new IllegalArgumentException("illegal value argument, please use value instend of value-ref!");
                }

                if (!(value instanceof String)) {
                    throw new IllegalArgumentException("illegal value argument,key:" + (String) entity.getKey() + ",a reference or bean name of type javax.sql.DataSource is required!");
                }

                String keyName = (String) value;
                Object valueBean = this.springContext.getBean(keyName);
                if (!(valueBean instanceof DataSource)) {
                    throw new IllegalArgumentException("illegal value argument,key:" + (String) entity.getKey() + ",a reference or bean name of type javax.sql.DataSource is required!");
                }

                this.dataSourceMap.put(entity.getKey(), (String) value);
                DataSource dataSource = (DataSource) valueBean;
                if (!(dataSource instanceof TransactionAwareDataSourceProxy)) {
                    ShardingDataSources.getInstance().addDataSource(keyName, new TransactionAwareDataSourceProxy(dataSource));
                }
            }

        }
    }
}